# coding: utf8


import uuid

import time
import tornado
from tornado import gen
from tornado.escape import json_decode
import time
import cms_config
from app.base_controller import BaseController
from app.common import global_space, wzhifuSDK
from app.common.common import get_price_and_transtrant_price
from app.models import VideoType, PriceType, VideoTime, PriceTypeDetail, VideoOrder, VideoOrderState, VideoOrderComment, GoodsOrder, AppUser, Teams
from libs.util import check_param
import logging as log
from django.db.models import Q

log.basicConfig(format='[%(asctime)s] [%(filename)s]:[line:%(lineno)d] [%(levelname)s] %(message)s', level=log.INFO)


# /api/video-type
class VideoTypeList(BaseController):

    def get(self):
        data = []
        for videoType in VideoType.objects.filter(state=0).order_by('show_order').all():
            data.append(videoType.to_dict())
        self.render_json(data=data)


# /api/video-time
class VideoTimeList(BaseController):

    def get(self):
        data = []
        for videoType in VideoTime.objects.filter(state=0).order_by('show_order').all():
            data.append(videoType.to_dict())
        self.render_json(data=data)


# /api/video-price
class VideoPrice(BaseController):
    def get(self):
        type = self.get_argument("videoType")
        param = [type, ]
        if check_param(param):
            self.render_json(code=1001, msg='参数丢失')
            return

        data = []
        for videoType in VideoType.objects.filter(state=0).filter(id=type).first().price_type.all():
            data.append(videoType.to_dict())
        self.render_json(data=data)


# /api/video-price-detail
class VideoOrderList(BaseController):
    def get(self):
        session_id = self.get_argument("session_id", '')
        if check_param(session_id):
            self.render_json(code=1001, msg='参数不全')
        session = global_space.very_session(session_id)
        if not session:
            self.render_json(code=999, msg='session 失效')
            return
        openid = session['openid']
        state = VideoOrderState.objects.filter(id__in=(99, 14)).all()
        vo = VideoOrder.objects.filter(openid=openid).filter(~Q(state__in=state)).select_related('video_type'). \
            select_related('video_time').prefetch_related('price_type_detail')
        paginator = self.pagination(vo.all(), page_num=int(self.get_argument("pageNum", 1)), photo_style='/710_476')
        return self.render_json(data=paginator)


class VideoOrderCount(BaseController):
    def get(self):
        session_id = self.get_argument("session_id", '')
        if check_param(session_id):
            self.render_json(code=1001, msg='参数不全')
        session = global_space.very_session(session_id)
        if not session:
            self.render_json(code=999, msg='session 失效')
            return
        openid = session['openid']
        state = VideoOrderState.objects.filter(id__in=(99, 14)).all()

        return self.render_json(data=VideoOrder.objects.filter(openid=openid).filter(~Q(state__in=state)).count() + GoodsOrder.objects.filter(openid=openid).filter(~Q(state__in=state)).count())


# /video-order-confirm
class VideoOrderConfirm(BaseController):
    def post(self):
        id = self.get_json_argument("id", '')
        session_id = self.get_json_argument("session_id", '')
        param = [id, session_id]
        if check_param(param):
            self.render_json(code=1001, msg='参数不全')
        session = global_space.very_session(session_id)
        if not session:
            self.render_json(code=999, msg='session 失效')
            return

        openid = session['openid']
        vo = VideoOrder.objects.filter(id=id).first()
        if not vo:
            self.render_json(code=1008, msg='订单不存在')
            return
        if vo.state.id != 99:
            self.render_json(code=1004, msg='此状态不允许下单')
            return
        if vo.openid != openid:
            self.render_json(code=1009, msg='不能修改别人的订单')
            return
        state = VideoOrderState.objects.filter(id=1).first()
        vo.state = state
        vo.save()
        return self.render_json(data={})


# /video-order-modify
class VideoOrderModify(BaseController):
    def post(self):
        id = self.get_json_argument("id", '')
        video_type = self.get_json_argument("video-type", '')
        video_time = self.get_json_argument("video-time", '')
        video_price = self.get_json_argument("video-price", [])
        requirement = self.get_json_argument("requirement", '')
        contacts = self.get_json_argument("contacts", '')
        phone = self.get_json_argument("phone", '')
        city = self.get_json_argument("city", '')
        second_city = self.get_json_argument("second_city", '')
        session_id = self.get_json_argument("session_id", '')

        param = [id, video_type, video_time, video_price, contacts, phone, city, session_id]
        if check_param(param):
            self.render_json(code=1001, msg='参数不全')
            return
        session = global_space.very_session(session_id)
        if not session:
            self.render_json(code=999, msg='session 失效')
            return

        openid = session['openid']

        v_type = VideoType.objects.filter().filter(id=video_type).prefetch_related('price_type').first()
        v_ptd = [key for key in PriceTypeDetail.objects.filter(id__in=video_price).all()]

        vtime = VideoTime.objects.filter(id=video_time).first()

        if not v_type or not vtime or len(v_ptd) != len(video_price):
            self.render_json(code=1002, msg='参数不正确')
            return
        price = 0
        for key in v_ptd:
            # log.info(key.price_type_detail_set.first().to_dict)
            price += key.transaction_price
        price = price * vtime.factor

        vo = VideoOrder.objects.filter(id=id).first()
        if not vo:
            self.render_json(code=1008, msg='订单不存在')
            return
        if vo.state.id not in (99, 1):
            self.render_json(code=1004, msg='此状态不允许修改')
            return
        if vo.openid != openid:
            self.render_json(code=1009, msg='不能修改别人的订单')
            return
        vo.city = city
        vo.second_city = second_city
        vo.video_type = v_type
        vo.video_time = vtime
        vo.requirement = requirement
        vo.contacts = contacts
        vo.phone = phone
        vo.openid = openid

        vo.price = price
        vo.price_type_detail.set(v_ptd)
        vo.save()
        self.render_json(data=vo.get_id())


class PayNotify(BaseController):
    def post(self):
        # log.info(self.request.body)
        data = wzhifuSDK.xml_to_dict(self.request.body.decode('utf-8'))
        openid = data.get('openid')
        out_trade_no = data.get('out_trade_no')
        total_fee = data.get('total_fee')
        transaction_id = data.get('transaction_id')
        vo = VideoOrder.objects.filter(openid=openid).filter(order_id=out_trade_no).first()
        vo.weixin_order_id = transaction_id
        vo.pay_amount = int(total_fee) / 100
        # if int(total_fee) / 100==vo.price:
        state = VideoOrderState.objects.filter(id=2).first()
        vo.state = state
        vo.save()
        self.write('''<xml>
                    <return_code>SUCCESS</return_code>
                    <return_msg>OK</return_msg>
                    </xml>''')


class Comments(BaseController):
    def post(self):
        id = self.get_json_argument("id", '')
        quality = self.get_json_argument("quality", '')
        service_attitude = self.get_json_argument("service_attitude", '')
        efficiency = self.get_json_argument("efficiency", '')
        remark = self.get_json_argument("remark", '')
        session_id = self.get_json_argument("session_id", '')
        param = [id, session_id, quality, service_attitude, efficiency, remark]
        if check_param(param):
            self.render_json(code=1001, msg='参数不全')
        session = global_space.very_session(session_id)
        if not session:
            self.render_json(code=999, msg='session 失效')
            return

        openid = session['openid']
        vo = VideoOrder.objects.filter(id=id).first()
        if not vo:
            self.render_json(code=1008, msg='订单不存在')
            return
        if vo.state.id != 9:
            self.render_json(code=1004, msg='此状态不允许评论')
            return
        if vo.openid != openid:
            self.render_json(code=1009, msg='不能修改别人的订单')
            return
        state = VideoOrderState.objects.filter(id=13).first()
        vo.state = state
        vo.save()
        VideoOrderComment.objects.create(quality=quality, service_attitude=service_attitude, efficiency=efficiency, remark=remark, video_order=vo)
        team = Teams.objects.filter(id=vo.team_id).first()
        if team:
            team.score = team.score+(quality+service_attitude+efficiency)
            team.score_cnt = team.score_cnt+1
            team.save()
        return self.render_json(data={})


class ChangeVideoStatus(BaseController):
    def post(self):
        id = self.get_json_argument("id", '')
        status = int(self.get_json_argument("status", ''))
        session_id = self.get_json_argument("session_id", '')
        remark = self.get_json_argument("remark", '')
        param = [id, status, session_id]
        if check_param(param):
            self.render_json(code=1001, msg='参数不全')
        session = global_space.very_session(session_id)
        if not session:
            self.render_json(code=999, msg='session 失效')
            return

        openid = session['openid']
        vo = VideoOrder.objects.filter(id=id).first()
        if not vo:
            self.render_json(code=1008, msg='订单不存在')
            return
        if vo.openid != openid:
            self.render_json(code=1009, msg='不能修改别人的订单')
            return
        if vo.state.id == 1 and status == 14:
            pass
        elif vo.state.id in (2, 3, 4, 5, 6, 7, 8) and status == 10:
            pass
        elif vo.state.id == 8 and status == 9:
            pass
        else:
            self.render_json(code=1009, msg='操作错误')
            return
        if status == 10:
            vo.back_remark = remark
            vo.save()
        state = VideoOrderState.objects.filter(id=status).first()
        vo.state = state
        vo.save()
        return self.render_json(data={})


class Pay(BaseController):
    @tornado.web.asynchronous
    def post(self):
        session_id = self.get_json_argument("session_id", '')
        if check_param(session_id):
            self.render_json(code=1001, msg='参数不全')
        session = global_space.very_session(session_id)
        if not session:
            self.render_json(code=999, msg='session 失效')
            return
        openid = session['openid']

        url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
        http = tornado.httpclient.AsyncHTTPClient()
        id = self.get_json_argument("id", '')
        remark = self.get_json_argument("remark", '')
        tax_unit = self.get_json_argument("tax_unit", '')
        tax_code = self.get_json_argument("tax_code", '')
        agree_show = self.get_json_argument("agree_show", 0)
        need_tax = self.get_json_argument("need_tax", 0)
        remote_ip = self.request.remote_ip
        param = [id, session_id]
        if check_param(param):
            self.render_json(code=1001, msg='参数不全')
            return
        vo = VideoOrder.objects.filter(id=id).first()

        if not vo:
            self.render_json(code=1008, msg='订单不存在')
            return
        if vo.state.id != 1:
            self.render_json(code=1004, msg='此状态不允许付款')
            return

        if vo.openid != openid:
            self.render_json(code=1009, msg='不能支付别人的订单')
            return
        if remark:
            vo.remark = remark
        if tax_unit:
            vo.tax_unit = tax_unit
        if tax_code:
            vo.tax_code = tax_code
        if agree_show != 0:
            vo.agree_show = agree_show
        if need_tax != 0:
            vo.need_tax = need_tax
        vo.save()

        data = {"appid": cms_config.app_id,
                "openid": vo.openid,
                "mch_id": cms_config.mch_id,
                "nonce_str": uuid.uuid1().hex,
                "body": "欢玺视频定制",
                "sign_type": "MD5",
                "out_trade_no": str(vo.order_id),
                "total_fee": str(1),
                "spbill_create_ip": remote_ip,
                "notify_url": "https://api.joyfulmedia.cn/api/video-order-notify",
                "trade_type": "JSAPI"
                }

        sign = wzhifuSDK.get_sign(data)
        data['sign'] = sign
        # log.info(wzhifuSDK.trans_dict_to_xml(data))
        http.fetch(url, method='POST', body=wzhifuSDK.trans_dict_to_xml(data),
                   callback=self.on_response)

    def on_response(self, response):
        if response.error:
            self.render_json(code=1002, msg='系统异常')
        else:
            sign_data = {}
            data = wzhifuSDK.xml_to_dict(response.body.decode('utf-8'))
            if data.get('return_code', '') == 'SUCCESS' and data.get('return_msg', '') == 'OK' and data.get('result_code', '') == 'SUCCESS':
                sign_data['nonceStr'] = uuid.uuid1().hex.upper()
                sign_data['signType'] = 'MD5'
                sign_data['timeStamp'] = str(int(time.time()))
                sign_data['appId'] = cms_config.app_id
                sign_data['package'] = 'prepay_id=' + data.get('prepay_id', '')
                sign_data['sign'] = wzhifuSDK.get_sign(sign_data)
                self.render_json(data=sign_data)
            else:
                self.render_json(code=9999, msg='系统错误')


class PriceDetail(BaseController):
    def get(self):
        id = self.get_argument("id", '')
        param = [id]
        if check_param(param):
            self.render_json(code=1001, msg='参数不全')
            return
        vo = PriceType.objects.filter(id=id).prefetch_related('price_type_detail')
        self.render_json(data=vo.first().to_dict())


# /video-order-create
class VideoOrderCreate(BaseController):
    def post(self):
        video_type = self.get_json_argument("video-type", '')
        video_time = self.get_json_argument("video-time", '')
        video_price = self.get_json_argument("video-price", [])
        requirement = self.get_json_argument("requirement", '')
        contacts = self.get_json_argument("contacts", '')
        phone = self.get_json_argument("phone", '')
        city = self.get_json_argument("city", '')
        second_city = self.get_json_argument("second_city", '')
        session_id = self.get_json_argument("session_id", '')

        param = [video_type, video_time, video_price, contacts, phone, city, session_id]
        if check_param(param):
            self.render_json(code=1001, msg='参数不全')
            return
        session = global_space.very_session(session_id)
        if not session:
            self.render_json(code=999, msg='session 失效')
            return

        openid = session['openid']

        user = AppUser.objects.filter(openid=openid).first()
        user.contact_name = contacts
        user.phone = phone
        user.save()

        v_type = VideoType.objects.filter(id=video_type).first()

        v_ptd = [key for key in PriceTypeDetail.objects.filter(id__in=video_price).all()]

        vtime = VideoTime.objects.filter(id=video_time).first()
        # VideoOrderStats.ob
        if not v_type or not vtime or len(v_ptd) != len(video_price):
            self.render_json(code=1002, msg='参数不正确')
            return

        price, final_transaction_price = get_price_and_transtrant_price(vtime.factor, v_ptd)

        data_str = time.strftime('%Y%m%d%H%M%S', time.localtime())
        order_id = data_str + str(global_space.get_order_id()).zfill(32 - len(data_str))

        data_str = time.strftime('%Y', time.localtime())
        id = data_str + str(global_space.get_order_id()).zfill(10 - len(data_str))

        log.info(price)
        state = VideoOrderState.objects.filter(id=99).first()
        vo = VideoOrder.objects.create(id=id, state=state, city=city, second_city=second_city, video_type=v_type, video_time=vtime, requirement=requirement,
                                       contacts=contacts, phone=phone, openid=openid, price=final_transaction_price, order_id=order_id)
        vo.price_type_detail.set(v_ptd)

        self.render_json(data=vo.get_id())


# /api/video-order-detail
class VideoOrderDetail(BaseController):
    def get(self):
        id = self.get_argument("id", '')
        session_id = self.get_argument("session_id", '')
        param = [id, session_id]
        if check_param(param):
            self.render_json(code=1001, msg='参数不全')
            return

        session = global_space.very_session(session_id)
        if not session:
            self.render_json(code=999, msg='session 失效')
            return

        vo = VideoOrder.objects.filter(id=id).select_related('video_type'). \
            select_related('video_time').prefetch_related('price_type_detail').first()
        if not vo:
            self.render_json(code=1002, msg='订单不存在')
            return
        openid = session['openid']
        if vo.openid != openid:
            self.render_json(code=1009, msg='不能查看别人的订单')
            return
        self.render_json(data=vo.to_dict(1))
